package com.aps.common.model;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

import java.util.List;
import java.util.Map;

/**
 * 标准APS参数模型
 * 用于后续排期算法的统一数据格式
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "标准APS参数模型")
public class APSProductModel {
    
    /**
     * 产品基本信息
     */
    @Schema(description = "产品基本信息")
    private Product product;
    
    /**
     * 生产订单列表
     */
    @Schema(description = "生产订单列表")
    private List<ProductionOrder> orders;
    
    /**
     * 工艺路线
     */
    @Schema(description = "工艺路线")
    private List<Operation> operations;
    
    /**
     * 资源信息
     */
    @Schema(description = "资源信息")
    private Resources resources;
    
    /**
     * 约束条件
     */
    @Schema(description = "约束条件")
    private Constraints constraints;
    
    /**
     * 元数据
     */
    @Schema(description = "元数据")
    private Map<String, Object> metadata;
    
    /**
     * 产品信息
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "产品信息")
    public static class Product {
        @Schema(description = "产品ID", example = "P001")
        private String id;
        
        @Schema(description = "产品名称", example = "汽车齿轮")
        private String name;
        
        @Schema(description = "产品类别", example = "齿轮")
        private String category;
        
        @Schema(description = "材料", example = "合金钢")
        private String material;
        
        @Schema(description = "产品规格")
        private Map<String, Object> specifications;
        
        @Schema(description = "年需求量", example = "10000")
        private Integer annualDemand;
        
        @Schema(description = "产品型号", example = "GEAR-001")
        private String model;
        
        @Schema(description = "产品规格描述")
        private String specification;
    }
    
    /**
     * 生产订单
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "生产订单")
    public static class ProductionOrder {
        @Schema(description = "订单ID", example = "ORD001")
        private String id;
        
        @Schema(description = "客户名称", example = "大众汽车")
        private String customerName;
        
        @Schema(description = "客户等级", example = "A")
        private String customerLevel;
        
        @Schema(description = "产品型号", example = "GEAR-001")
        private String productModel;
        
        @Schema(description = "订单数量", example = "1000")
        private Integer quantity;
        
        @Schema(description = "交期", example = "2024-06-30")
        private String deliveryDate;
        
        @Schema(description = "优先级", example = "高")
        private String priority;
        
        @Schema(description = "订单金额", example = "50000.00")
        private Double orderAmount;
        
        @Schema(description = "优先级分数", example = "0.9")
        private Double priorityScore;
        
        @Schema(description = "关键比率", example = "1.2")
        private Double criticalRatio;
    }
    
    /**
     * 工序信息
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "工序信息")
    public static class Operation {
        @Schema(description = "工序ID", example = "OP001")
        private String id;
        
        @Schema(description = "工序名称", example = "车削")
        private String name;
        
        @Schema(description = "工序序号", example = "1")
        private Integer sequence;
        
        @Schema(description = "设备类型", example = "车床")
        private String equipmentType;
        
        @Schema(description = "标准工时(分钟)", example = "30.0")
        private Double standardTime; // 分钟
        
        @Schema(description = "换型时间(分钟)", example = "15.0")
        private Double setupTime; // 分钟
        
        @Schema(description = "人员要求", example = "中级车工")
        private String personnelRequirement;
        
        @Schema(description = "质量要求", example = "表面粗糙度Ra1.6")
        private String qualityRequirement;
        
        @Schema(description = "前置工序列表")
        private List<String> predecessorOperations;
        
        @Schema(description = "后置工序列表")
        private List<String> successorOperations;
        
        @Schema(description = "所需资源列表")
        private List<String> requiredResources;
        
        @Schema(description = "约束条件")
        private Map<String, Object> constraints;
    }
    
    /**
     * 资源信息
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "资源信息")
    public static class Resources {
        @Schema(description = "设备资源列表")
        private List<EquipmentResource> equipment;
        @Schema(description = "人员资源列表")
        private List<PersonnelResource> personnel;
    }
    
    /**
     * 设备资源
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "设备资源")
    public static class EquipmentResource {
        @Schema(description = "设备ID", example = "EQ001")
        private String id;
        @Schema(description = "设备名称", example = "CNC车床")
        private String name;
        @Schema(description = "设备类型", example = "加工设备")
        private String type;
        @Schema(description = "每日产能(分钟)", example = "480.0")
        private Double dailyCapacity; // 分钟
        @Schema(description = "效率因子", example = "0.95")
        private Double efficiencyFactor;
        @Schema(description = "维护计划")
        private String maintenanceSchedule;
        @Schema(description = "状态", example = "正常")
        private String status;
        @Schema(description = "能力列表")
        private List<String> capabilities;
        @Schema(description = "换型时间矩阵")
        private Map<String, Double> setupTimeMatrix;
    }
    
    /**
     * 人员资源
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "人员资源")
    public static class PersonnelResource {
        @Schema(description = "人员ID", example = "PER001")
        private String id;
        @Schema(description = "人员名称", example = "张三")
        private String name;
        @Schema(description = "岗位类型", example = "操作工")
        private String jobType;
        @Schema(description = "技能等级", example = "高级")
        private String skillLevel;
        @Schema(description = "每日工作时长(小时)", example = "8.0")
        private Double dailyWorkHours; // 小时
        @Schema(description = "可操作设备列表")
        private List<String> operableEquipment;
        @Schema(description = "状态", example = "在职")
        private String status;
        @Schema(description = "技能列表")
        private List<String> skills;
        @Schema(description = "效率因子", example = "1.0")
        private Double efficiencyFactor;
        
        @Schema(description = "岗位", example = "操作工")
        private String position;
    }
    
    /**
     * 约束条件
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "约束条件")
    public static class Constraints {
        @Schema(description = "硬约束列表")
        private List<HardConstraint> hardConstraints;
        @Schema(description = "软约束列表")
        private List<SoftConstraint> softConstraints;
    }
    
    /**
     * 硬约束
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "硬约束")
    public static class HardConstraint {
        @Schema(description = "约束ID", example = "HC001")
        private String id;
        @Schema(description = "约束类型", example = "时间")
        private String type;
        @Schema(description = "约束描述", example = "订单必须在指定时间内完成")
        private String description;
        @Schema(description = "优先级", example = "高")
        private String priority;
        @Schema(description = "约束参数")
        private Map<String, Object> parameters;
    }
    
    /**
     * 软约束
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Schema(description = "软约束")
    public static class SoftConstraint {
        @Schema(description = "约束ID", example = "SC001")
        private String id;
        @Schema(description = "约束类型", example = "成本")
        private String type;
        @Schema(description = "约束描述", example = "总成本不能超过预算")
        private String description;
        @Schema(description = "权重", example = "0.7")
        private Double weight;
        @Schema(description = "约束参数")
        private Map<String, Object> parameters;
    }
}
